﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace Jemgine.MapEditor.Operations
{
	internal class Delete : Operation
	{
        class Item : IComparable<Item>
        {
            internal Engine.Selection _object;
            internal Object StoredObject;

            public override int GetHashCode()
            {
                return _object.GetHashCode();
            }

            public override bool Equals(object obj)
            {
                if (!(obj is Item)) return false;
                return this._object == ( obj as Item )._object;
            }

           #region IComparable<Item> Members

            public int CompareTo(Item other)
            {
                return _object.CompareTo(other._object);
            }

            #endregion
        }

        List<Item> ToDelete = new List<Item>();

        public Delete(Engine.Selection What)
		{
            if (What.Type != Jemgine.Engine.Selection.Types.None)
                ToDelete.Add(new Item { _object = What });
		}

        public Delete(Engine.Selection What, List<Engine.Selection> MultiWhat)
        {
            if (What.Type != Jemgine.Engine.Selection.Types.None)
                ToDelete.Add(new Item { _object = What });
            foreach (var Selection in MultiWhat)
                if (Selection.Type != Jemgine.Engine.Selection.Types.None)
                    ToDelete.Add(new Item { _object = Selection });
        }

		internal override ReturnCode Do(EditorState ES)
		{
            ToDelete.Sort();

            for (int I = ToDelete.Count - 1; I >= 0; --I)
            {
                var _object = ToDelete[I]._object;
                var StoredObject = ES.GetSelectionObject(_object);
                ToDelete[I].StoredObject = StoredObject;
                if (StoredObject is Data.MapElement) ( StoredObject as Data.MapElement ).ClearAllIDs();

                switch (_object.Type)
                {
                    case Jemgine.Engine.Selection.Types.MapElement:
                        ES.Map.Elements.RemoveAt(_object.TopIndex);
                        break;
                    case Jemgine.Engine.Selection.Types.EntityElement:
                        ( ES.Map.Elements[_object.TopIndex] as Data.EntityRecord ).AttachedElements.RemoveAt(_object.MiddleIndex);
                        break;
                    case Jemgine.Engine.Selection.Types.Vertex:
                        var Poly = ES.GetMiddleObject(_object) as Data.EditorPolygon;
                        if (Poly == null) return ReturnCode.DoNotAddToUndoStack;
                        else
                        {
                            Poly.RemoveAt(_object.BottomIndex);
                            Poly.ClearDecomposedCache();
                        }
                        break;
                    default:
                        return ReturnCode.DoNotAddToUndoStack;
                }
            }

            ES.SelectItem(Engine.Selection.None);
            ES._RebuildTree();

			return ReturnCode.AddToUndoStack;
		}

		internal override void Undo(EditorState ES)
		{
            for (int I = 0; I < ToDelete.Count; ++I)
            {
                var _object = ToDelete[I]._object;
                var StoredObject = ToDelete[I].StoredObject;
                switch (_object.Type)
                {
                    case Jemgine.Engine.Selection.Types.MapElement:
                        ES.Map.Elements.Insert(_object.TopIndex, (Data.MapElement)StoredObject);
                        break;
                    case Engine.Selection.Types.EntityElement:
                        ( ES.Map.Elements[_object.TopIndex] as Data.EntityRecord ).AttachedElements.Insert(_object.MiddleIndex, (Data.EntityElement)StoredObject);
                        break;
                    case Engine.Selection.Types.Vertex:
                        (ES.GetMiddleObject(_object) as Data.EditorPolygon).Insert(_object.BottomIndex, (Data.Vertex)StoredObject);
                        (ES.GetMiddleObject(_object) as Data.EditorPolygon).ClearDecomposedCache();
                        break;
                }
            }

            ES.SelectItem(Jemgine.Engine.Selection.None);
            ES._RebuildTree();
		}
	}
}
